import os
import time

import allure
from appium import webdriver
from appium.options.common import AppiumOptions
from appium.webdriver.common.appiumby import AppiumBy
from faker import Faker
from selenium.common import NoSuchElementException
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


@allure.feature("企业微信成员,重复添加,删除成员")
class Testweixin:
    def setup_class(self):
        # 配置启动参数
        self.desired_caps = {}
        self.desired_caps['platformName'] = 'Android'
        self.desired_caps['platformVersion'] = '12'
        self.desired_caps['deviceName'] = '127.0.0.1:7555'
        self.desired_caps['udid'] = '127.0.0.1:7555'
        self.desired_caps['newCommandTimeout'] = 60
        self.desired_caps['noReset'] = True
        # 配置参数老控制app启动关闭
        self.desired_caps["appium:forceAppLaunch"] = True
        # desired_caps["appium:shouldTerminateApp"] = True
        # 配置驱动
        self.desired_caps["automationName"] = 'uiautomator2'
        self.desired_caps["dontStopAppOnReset"] = True
        self.desired_caps["adbExecTimeout"] = 30000
        # com.android.settings/com.android.settings.Settings
        self.desired_caps['appPackage'] = 'com.tencent.wework'
        self.desired_caps['appActivity'] = 'com.tencent.wework.launch.LaunchSplashActivity'
        options = AppiumOptions().load_capabilities(self.desired_caps)
        # server 版本启动地址：http://127.0.0.1:4723
        # gui 版本启动地址：http://127.0.0.1:4723/wd/hub
        self.driver = webdriver.Remote('http://127.0.0.1:4723', options=options)

        fake = Faker('zh_CN')
        self.name = fake.name()
        self.phone_number = fake.phone_number()

    def teardown_class(self):

        os.system(f"adb -s {self.desired_caps['udid']} shell am force-stop com.tencent.wework")
        print("关闭app")
        self.driver.quit()

    def back_to_main_page(self):
        """返回主页面"""
        # 获取当前界面的activity
        current_activity = self.driver.current_activity
        # 如果不是当前界面的主界面，返回主页面,递归返回
        if current_activity != ".launch.WwMainActivity":
            self.driver.back()
            self.back_to_main_page()

    def test_add_contact(self):
        # 调用添加输入信息
        self.input_contact_info()
        # 获取点击保存后提示文本
        with allure.step("获取tips文本"):
            tips = WebDriverWait(self.driver, 10, 1).until(expected_conditions.presence_of_element_located(
                (AppiumBy.XPATH, "//*[@class='android.widget.Toast']"))).text
            self.allure_step_image("tips文本")
        print(self.phone_number)

        self.back_to_main_page()
        assert tips == "添加成功"

    def test_add_add_contact_fail(self):
        self.input_contact_info()
        with allure.step("获取弹窗文本"):
            result = WebDriverWait(self.driver, 10, 1).until(
                expected_conditions.visibility_of_element_located(
                    ((AppiumBy.XPATH,
                      "//*[@class='android.widget.ScrollView']//*[@class='android.widget.TextView']")))).text

        assert result == "手机已存在于通讯录，无法添加"
        self.back_to_main_page()

    def test_del_contact(self):
        """数据清理，测试删除"""
        # 点击管理成员，进入管理成员页面
        with allure.step("进入管理成员页面"):
            self.driver.find_element(AppiumBy.XPATH, "//*[@resource-id='com.tencent.wework:id/lf5']").click()
            self.allure_step_image("管理成员页面")
        # 进入编辑成员页
        with allure.step("滑动查找元素编辑成员"):
            self.swip_find(AppiumBy.XPATH, f"//*[@text='{self.name}']/../../..").click()
            self.allure_step_image("编辑成员页")
        # 点击删除
        with allure.step("点击删除成员"):
            self.swip_find(AppiumBy.XPATH, "//*[@resource-id='com.tencent.wework:id/gvm']")
            WebDriverWait(self.driver, 10, 1).until(expected_conditions.presence_of_element_located(
                (AppiumBy.XPATH, "//*[@resource-id='com.tencent.wework:id/gvm']"))).click()
            self.allure_step_image("删除成员弹窗")
            # 点击确认删除
            WebDriverWait(self.driver, 10, 1).until(expected_conditions.presence_of_element_located(
                (AppiumBy.XPATH, "//*[@text='删除']"))).click()
        # 返回成员列表
        with allure.step("回到通讯录页"):
            self.back_to_main_page()
            self.allure_step_image("通讯录页")
        with allure.step("搜索删除后的人"):
            # 点击搜索
            self.driver.find_element(AppiumBy.XPATH, "//*[@resource-id='com.tencent.wework:id/lf_']").click()
            self.allure_step_image("获取搜索框")
            # 输入姓名
            self.driver.find_element(AppiumBy.XPATH, "//*[@class='android.widget.EditText']").send_keys(self.name)
            self.allure_step_image("搜索姓名")
        # 断言无搜索结果
        with allure.step("断言无搜索结果"):
            result = WebDriverWait(self.driver, 10, 1).until(
                expected_conditions.visibility_of_element_located(
                    (AppiumBy.XPATH, "//*[@resource-id='com.tencent.wework:id/dk4']"))).text
            self.allure_step_image("断言无搜索结果")
        assert result == "无搜索结果"

    def input_contact_info(self):
        with allure.step("进入添加成员"):
            # 点击通讯录
            WebDriverWait(self.driver, 60, 1).until(expected_conditions.presence_of_element_located(
                (AppiumBy.XPATH, "//*[@text='通讯录']"))).click()
            self.allure_step_image("进入通讯录")
            # 滑动找元素并点击，点击添加成员
            self.swip_find(AppiumBy.XPATH, "//*[@text='添加成员']").click()
            self.allure_step_image("进入添加成员")
            # 点击手动输入添加
            self.driver.find_element(AppiumBy.XPATH, "//*[@text='手动输入添加']").click()
            self.allure_step_image("输入手机号，姓名页")
        with allure.step("输入姓名，手机号"):
            # 输入姓名
            WebDriverWait(self.driver, 10, 1).until(
                expected_conditions. \
                    element_to_be_clickable \
                    ((AppiumBy.XPATH, "//*[@text='姓名']/following-sibling::*[1]"))).send_keys(self.name)
            # 输入手机号
            self.driver.find_element(AppiumBy.XPATH,
                                     "//*[@text='手机']/following-sibling::*/child::*[2]/child::*").send_keys(
                self.phone_number)
            self.allure_step_image("查看输入手机号，姓名")
        with allure.step("点击保存"):
            # 点击保存
            self.driver.find_element(AppiumBy.XPATH, "//*[@text='保存']").click()
            self.allure_step_image("点击保存后弹窗")

    def swipe_window(self):
        """滑动界面"""
        # 获取设备尺寸,返回字典 # {"width": xx, "height": xx}
        size = self.driver.get_window_size()
        # 获取高度宽度
        width = size.get("width")
        height = size.get("height")
        # 获取滑动坐标
        start_x = width / 2
        start_y = height * 0.8
        end_x = start_x
        end_y = height * 0.2
        self.driver.swipe(start_x, start_y, end_x, end_y, 2000)

    def swip_find(self, by, ele):
        '''
        滑动查找
        通过文本来查找元素，如果没有找到元素，就滑动，
        如果找到了，就返回元素
        '''
        self.driver.implicitly_wait(1)
        for num in range(10):
            try:
                ele = self.driver.find_element(by, ele)
                self.driver.implicitly_wait(5)
                print(ele)
                return ele
            except Exception:
                # 当元素发生异常时
                print(f"第{num}次没有找到{ele}元素")
                print(f"开始滑动{num + 1}次")
                self.swipe_window()
        # 把隐式等待恢复原来的时间
        self.driver.implicitly_wait(10)
        # 抛出找不到元素的异常
        raise NoSuchElementException(f"滑动之后，未找到 {ele} 元素")

    def screenshot(self):
        '''
        截图
        :param path: 截图保存路径
        '''
        cur_time = time.strftime("%Y-%m-%d-%H-%M-%S")
        file_path = cur_time + ".png"
        path = os.sep.join([root_path, "screenshot"])
        if not os.path.isdir(path):
            os.mkdir(path)
        # 截图保存路径
        source_path = os.sep.join([path, file_path])
        self.driver.save_screenshot(source_path)

        return source_path

    def allure_step_image(self, name):
        time.sleep(1)
        path = self.screenshot()
        allure.attach.file(source=path, name=name, attachment_type=allure.attachment_type.PNG)
